using Pay.Core;
using Pay.Data;
using Pay.DTO;
using Pay.DTO.htl;
using Pay.IService;
using Pay.Service.Cache;
using Pay.TO;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pay.Service {
    public class OrderService : MerchantBillService, IOrderService, IDisposable {
        private IUnitOfWork _iUnitOfWork;
        private SxyPaySign _sxyPaySign;
        private IShippingAddressService _iShippAddressService;
        private IProductService _iProductService;
        private IRegionService _iRegionService;
        private IGradeService _iGradeService;
        private ILogisticsDetailsService _iLogisticsDetailsService;
        private ITokenBillService _iTokenBillService;
        private IProductActivityService _iProductActivityService;
        private IRedRecordService _iRedRecordService;

        public OrderService(IUnitOfWork iUnitOfWork, ISettingService iSettingService,
                            IProductService iProductService, IRegionService iRegionService,
                            IGradeService iGradeService, ILogisticsDetailsService iLogisticsDetailsService,
                            IBillService iBillService, IShippingAddressService iShippAddressService,
                            IMerchantService iMerchantService, IPaymentService iPaymentService,
                            IPayHtmlService iPayHtmlService, IPayNotifyService iPayNotifyService,
                            ITokenBillService iTokenBillService, IProductActivityService iProductActivityService,
                            IRedRecordService iRedRecordService)
                            : base(iUnitOfWork, iSettingService, iBillService, iMerchantService,
                                   iPaymentService, iPayHtmlService, iPayNotifyService) {
            _iUnitOfWork = iUnitOfWork;
            _sxyPaySign = new SxyPaySign();
            _iShippAddressService = iShippAddressService;
            _iProductService = iProductService;
            _iRegionService = iRegionService;
            _iGradeService = iGradeService;
            _iLogisticsDetailsService = iLogisticsDetailsService;
            _iTokenBillService = iTokenBillService;
            _iProductActivityService = iProductActivityService;
            _iRedRecordService = iRedRecordService;
        }

        /// <summary>
        /// 订单查询
        /// </summary>
        /// <param name="orderQuery"></param>
        /// <returns></returns>
        /// 
        public PagedResult<order_dto> Get(OrderQuery orderQuery) {
            var filter = PredicateBuilder.True<Order>();
            //过滤删除的订单
            filter = filter.And(c => c.Status != OrderStatus.Delete);
            if (orderQuery.distribution_id > 0 && orderQuery.merchant_id > 0 && orderQuery.shop_id > 0)//显示分销订单和自营订单，且用户有店铺
                filter = filter.And(c => c.DistributionId == orderQuery.distribution_id || c.MerchantId == orderQuery.merchant_id || c.ShopId == orderQuery.shop_id);
            else if (orderQuery.distribution_id > 0 && orderQuery.merchant_id > 0)//显示分销订单和自营订单
                filter = filter.And(c => c.DistributionId == orderQuery.distribution_id || c.MerchantId == orderQuery.merchant_id);
            else if (orderQuery.distribution_id > 0)//仅显示分销订单
                filter = filter.And(c => c.DistributionId == orderQuery.distribution_id);
            if (orderQuery.user_id > 0)
                filter = filter.And(c => c.BuyId == orderQuery.user_id && !c.IsBuyDel);
            if (orderQuery.merchant_id > 0 && orderQuery.distribution_id == 0)
                filter = filter.And(c => (c.MerchantId == orderQuery.merchant_id || c.Merchant.OemId == orderQuery.merchant_id) && !c.IsSellDel);
            if (!string.IsNullOrEmpty(orderQuery.order_no))
                filter = filter.And(c => c.OrderNo.Contains(orderQuery.order_no) || c.PayInfo.TransactionNo.Contains(orderQuery.order_no));
            if (!string.IsNullOrEmpty(orderQuery.merchant_no))
                filter = filter.And(c => c.Merchant.MerchantNo == orderQuery.merchant_no);
            if (orderQuery.order_status != OrderStatus.None)
                filter = filter.And(c => c.Status == orderQuery.order_status);
            if (orderQuery.push_status != OrderPushStatus.None)
                filter = filter.And(c => c.PushStatus == orderQuery.push_status);
            if (orderQuery.order_type.HasValue) {
                if (orderQuery.order_type.Value == 0)
                    filter = filter.And(c => c.OrderType == null || c.OrderType == 0);
                else
                    filter = filter.And(c => c.OrderType == orderQuery.order_type.Value);
            }
            if (!string.IsNullOrEmpty(orderQuery.q))
                filter = filter.And(c => c.Buyer.Name.Contains(orderQuery.q) || c.Buyer.Mobile.Contains(orderQuery.q) || c.Shipping.ShipTo.Contains(orderQuery.q) || c.Shipping.Phone.Contains(orderQuery.q));
            var start_time = orderQuery.start_time.ToUnix();
            if (orderQuery.start_time.HasValue && orderQuery.end_time.HasValue) {
                var end_time = orderQuery.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.OrderTime >= start_time && c.OrderTime <= end_time);
            } else if (orderQuery.start_time.HasValue && !orderQuery.end_time.HasValue)
                filter = filter.And(c => c.OrderTime >= start_time);
            else if (!orderQuery.start_time.HasValue && orderQuery.end_time.HasValue) {
                var end_time = orderQuery.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.OrderTime <= end_time);
            }
            if (orderQuery.type.GetValueOrDefault(0) > 0) {
                if (orderQuery.type.Value == 1) {//商城商品
                    filter = filter.And(c => c.OrderType <= 6);
                } else {
                    filter = filter.And(c => c.OrderType == 6);
                }
            }
            if (orderQuery.user_id > 0)
                return context.Orders.FromCachePaged<Order, order_dto>(orderQuery.page, orderQuery.size, filter, orderBy => orderBy.OrderByDescending(c => c.OrderTime));
            else
                return context.Orders.FromCachePaged<Order, order_dto>(orderQuery.page, orderQuery.size, filter, orderBy => orderBy.OrderByDescending(c => c.OrderTime));
        }

        /// <summary>
        /// 订单查询
        /// </summary>
        /// <param name="orderQuery"></param>
        /// <returns></returns>
        public List<Order> Gets(OrderQuery orderQuery) {
            var filter = PredicateBuilder.True<Order>();
            var linq = from order in context.Orders select order;
            if (orderQuery.merchant_id > 0)
                linq = linq.Where(x => x.MerchantId == orderQuery.merchant_id);
            if (orderQuery.order_status != OrderStatus.None)
                linq = linq.Where(x => x.Status == orderQuery.order_status);
            if (orderQuery.user_id > 0)
                linq = linq.Where(c => c.BuyId == orderQuery.user_id);
            if (orderQuery.order_type > 0)
                linq = linq.Where(c => c.OrderType == orderQuery.order_type);
            var start_time = orderQuery.start_time.ToUnix();
            if (orderQuery.start_time.HasValue && orderQuery.end_time.HasValue) {
                var end_time = orderQuery.end_time.Value.AddDays(1).ToUnix();
                linq = linq.Where(c => c.OrderTime >= start_time && c.OrderTime <= end_time);
            } else if (orderQuery.start_time.HasValue && !orderQuery.end_time.HasValue)
                linq = linq.Where(c => c.OrderTime >= start_time);
            else if (!orderQuery.start_time.HasValue && orderQuery.end_time.HasValue) {
                var end_time = orderQuery.end_time.Value.AddDays(1).ToUnix();
                linq = linq.Where(c => c.OrderTime <= end_time);
            }
            return linq.OrderByDescending(x => x.OrderTime).ToList();
        }


        /// <summary>
        /// 查询订单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public order_dto Get(long id) {
            return context.Orders.Find(id).ToDtoObject<order_dto>();
        }

        /// <summary>
        /// 查询订单
        /// </summary>
        /// <param name="order_no"></param>
        /// <returns></returns>
        public order_dto Get(string order_no) {
            return context.Orders.FirstOrDefault(c => c.OrderNo == order_no).ToDtoObject<order_dto>();
        }

        public List<order_dto> GetListByPayId(long PayId) {
            return context.Orders.Where(c => c.PayId == PayId).FromCache<Order, order_dto>();
        }

        public List<order_dto> GetOrdersByOrderNo(string orderNo) {
            var order = context.Orders.FirstOrDefault(c => c.OrderNo == orderNo);
            return context.Orders.Where(c => c.PayId == order.PayId).ToList().ToDtoList<order_dto>();
        }

        private static readonly object dbwaitLock = new object();
        /// <summary>
        /// 再支付成功后创建商品订单
        /// </summary>
        /// <returns>The add.</returns>
        /// <param name="payHtml">Pay html.</param>
        /// <param name="transaction_no">Transaction no.</param>
        /// <param name="pay_time">Pay time.</param>
        public int PaySuceess(pay_html_dto payHtml, string transaction_no, DateTime? pay_time) {
            lock (dbwaitLock) {
                List<string> cacheList = new List<string>();
                var charge_dto = payHtml.charge.ToObject<charge_dto>();
                if (charge_dto.status != ChargeStatus.WaitPay)
                    throw new ServerErrorException("付款" + charge_dto.order_no + "非待支付状态时", 1002);
                var db_order = context.Charges.FirstOrDefault(c => c.MerchantId == charge_dto.merchant_id && c.PayInfo.PayNo == charge_dto.order_no);
                if (db_order != null) return 0;
                var charge = charge_dto.ToDtoObject<Charge>();
                var payinfo = charge_dto.pay_info.ToDtoObject<PayInfo>();
                payinfo.TransactionNo = transaction_no;
                payinfo.PayTime = (pay_time ?? DateTime.Now).ToUnix();
                charge.OrderTime = DateTime.Now.ToUnix();
                charge.Status = ChargeStatus.Finish;
                charge.PayInfo = payinfo;
                charge.PlatFee = charge_dto.plat_fee;
                charge.PlatSettle = charge_dto.plat_settle;
                charge.PayInfo.CreateTime = charge.OrderTime;
                context.Charges.Add(charge);

                var ord_htmls = payHtml.html.ToObject<List<order_dto>>();
                var buyid = ord_htmls.FirstOrDefault().buy_id;
                foreach (var ord_html in ord_htmls) {
                    var order = ord_html.ToDtoObject<Order>();
                    order.PayInfo = payinfo;
                    if (ord_html.shipping_type == 4)
                        order.Status = OrderStatus.Finish;
                    else if (ord_html.shipping_type == 2)
                        order.Status = OrderStatus.Confirm;
                    else if (ord_html.shipping_type == 3)
                        order.Status = OrderStatus.WaitDelivery;
                    else
                        order.Status = OrderStatus.WaitDelivery;
                    order.OrderTime = payHtml.create_time.ToUnix();
                    order.OrderItems.ForEach(c => {
                        if (string.IsNullOrEmpty(c.SkuPath))
                        {
                            c.Integral = 0;
                            c.IsOpen = false;
                            c.Points = 0;
                            c.SkuPath = "123";
                            c.ActiveType = 0;
                        }
                    });

                    context.Orders.Add(order);
                    //更新对应商品的销量，扣减商品库存
                    order.OrderItems.ForEach(c => {
                        if (order.OrderType == 6) {
                            var product = context.TokenBazaarProduct.FirstOrDefault(s => s.Id == c.BazaarProductId);
                            product.Num -= 1;
                            cacheList.Add("TokenBazaarProduct" + c.BazaarProductId);
                        } else if (order.OrderType == 7) {
                        } else if (order.OrderType == 4) {
                            return;
                        } else {
                            var product = context.Products.FirstOrDefault(s => s.Id == c.ProductId);
                            if (product != null)
                                product.SaleCount += c.Quantity;
                            var item = context.ProductSkus.FirstOrDefault(s => s.ProductId == c.ProductId && s.SkuPath == c.SkuPath);
                            if (item != null)
                                item.Stock -= c.Quantity;
                            product.Stock -= c.Quantity;

                            if (c.ProductActivityId != null && c.ProductActivityId > 0) {//活动商品

                                var productActivity = context.ProductActivity.FindById(c.ProductActivityId);
                                if (productActivity != null) {
                                    //1.增加销售量
                                    productActivity.SaleCount += c.Quantity;
                                    //2.增加参与数
                                    if (productActivity.Activity != null)
                                        productActivity.Activity.ParticipationNum += 1;
                                    //3.扣减活动库存
                                    productActivity.ActivityStock -= c.Quantity;
                                    //4.判断限时购是否售罄
                                    if (product != null && (product.Stock <= 0 || productActivity.ActivityStock <= 0) && productActivity.ProductActivityTimeBuy != null) {
                                        productActivity.IsSoldOut = true;
                                    }
                                }

                                cacheList.Add("ProductActivity" + c.ProductId);
                                cacheList.Add("Activity");
                            }

                            cacheList.Add("Product" + c.ProductId);
                        }
                    });
                }
                //用于跨境电商做账业务
                if (charge.PayInfo.PayChannel == PayChannel.SxyPay)
                    OverSeasMallAccount(charge, ord_htmls);
                else if (charge.PayInfo.PayChannel == PayChannel.H5Pay)
                    H5MallAccount(charge, ord_htmls);
                else
                    //用于原先时代云商一些OEM商户做账
                    MallMerchantAccount(charge, ord_htmls);

                cacheList.Add(buyid.HasValue ? "Orders" + buyid : "");
                int result = _iUnitOfWork.Commit(cacheList.ToArray());
                return result;
            }
        }

        public int WaitPayOrder(pay_html_dto payHtml) {
            var charge_dto = payHtml.charge.ToObject<charge_dto>();
            var db_charge = context.Charges.FirstOrDefault(c => c.MerchantId == charge_dto.merchant_id && c.PayInfo.PayNo == charge_dto.order_no);
            if (db_charge != null) return 0;
            var charge = charge_dto.ToDtoObject<Charge>();
            var payinfo = charge_dto.pay_info.ToDtoObject<PayInfo>();
            payinfo.CreateTime = DateTime.Now.ToUnix();
            charge.OrderTime = DateTime.Now.ToUnix();
            charge.Status = ChargeStatus.WaitPay;
            charge.PayInfo = payinfo;
            charge.PayInfo.CreateTime = charge.OrderTime;
            context.Charges.Add(charge);

            var ord_htmls = payHtml.html.ToObject<List<order_dto>>();
            var buyid = ord_htmls.FirstOrDefault().buy_id;
            foreach (var ord_html in ord_htmls) {
                var order = ord_html.ToDtoObject<Order>();
                bool has_order = context.Orders.Any(c => c.OrderNo == order.OrderNo);
                if (has_order) return 0;
                order.PayInfo = payinfo;
                order.Status = OrderStatus.WaitPay;
                order.OrderTime = payHtml.create_time.ToUnix();
                context.Orders.Add(order);

            }

            int result = _iUnitOfWork.Commit(buyid.HasValue ? "Orders" + buyid : "", "Cart");
            return result;
        }
        /// <summary>
        /// 创建多单待支付订单
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int WaitPayOrder(mall_model model) {
            long? buyid = null;
            foreach (var order in model.orders) {
                var db_order = context.Orders.FirstOrDefault(c => c.OrderNo == order.order_no);
                if (db_order != null) {
                    db_order.PayInfo.PayNo = model.order_no;
                    buyid = db_order.BuyId;
                } else {
                    var order_table = order.ToDtoObject<Order>();
                    order_table.PayInfo = new PayInfo {
                        OrderNo = order.order_no,
                        PayNo = model.order_no,
                        PayChannel = model.pay_channel,
                        PayCode = model.pay_code,
                        PayType = model.pay_type,
                        PayName = model.pay_channel.ToDescription(),
                        CreateTime = DateTime.Now.ToUnix(),
                        SettleType = "T0"
                    };
                    order_table.Status = OrderStatus.WaitPay;
                    order_table.OrderTime = DateTime.Now.ToUnix();
                    buyid = order.buy_id;
                    if (order_table.OrderType == 1 || order_table.OrderType == 2)
                        order_table.PushStatus = OrderPushStatus.UnPush;
                    //如果店铺有设置收转账户，以店铺设置账户为准。
                    var shop = context.ShopInfo.FirstOrDefault(c => c.Id == order.merchant_id);
                    if (shop != null && shop.RedDrillReceiverId.HasValue && shop.RedDrillReceiverId.Value > 0) {
                        order_table.RedDrillReceiverId = shop.RedDrillReceiverId.Value;
                    }
                    context.Orders.Add(order_table);
                }
                if (model.source_type == 1) {
                    foreach (var item in order.order_items) {
                        if (order.buy_id.GetValueOrDefault(0) > 0) {
                            context.Carts.Remove(s => s.MerchantId == order.buy_id && s.SkuId == item.sku_id && s.ProductId == item.product_id);
                        }
                    }
                }
            }
            int result = _iUnitOfWork.Commit(buyid.HasValue ? "Orders" + buyid : "", "Cart");
            return result;
        }

        /// <summary>
        /// H5支付成功更新订单
        /// </summary>
        /// <returns>The h5 success.</returns>
        /// <param name="payHtml">Pay html.</param>
        /// <param name="transaction_no">Transaction no.</param>
        /// <param name="pay_time">Pay time.</param>
        public int PayH5Success(pay_html_dto payHtml, string transaction_no, DateTime? pay_time) {
            lock (dbwaitLock) {
                var charge_dto = payHtml.charge.ToObject<charge_dto>();
                if (charge_dto.status != ChargeStatus.WaitPay)
                    throw new ServerErrorException("付款" + charge_dto.order_no + "非待支付状态时", 1002);
                var db_order = context.Charges.FirstOrDefault(c => c.MerchantId == charge_dto.merchant_id && c.PayInfo.PayNo == charge_dto.order_no);
                if (db_order != null && db_order.Status == ChargeStatus.Finish) return 0;
                db_order.Status = ChargeStatus.Finish;
                var charge = charge_dto.ToDtoObject<Charge>();
                db_order.PayInfo.TransactionNo = transaction_no;
                db_order.PayInfo.PayTime = pay_time.ToUnix();
                charge.PayId = db_order.PayId;
                charge.OrderTime = db_order.OrderTime;
                var ord_htmls = payHtml.html.ToObject<List<order_dto>>();
                var buyid = ord_htmls.FirstOrDefault().buy_id;
                foreach (var ord_html in ord_htmls) {
                    var html = ord_html.ToDtoObject<Order>();
                    var order = context.Orders.FirstOrDefault(c => c.OrderNo == html.OrderNo);
                    if (order.Status != OrderStatus.WaitPay)
                        throw new ServerErrorException("付款" + html.OrderNo + "非待支付状态时", 1002);
                    order.Status = OrderStatus.WaitDelivery;
                    order.PayInfo.TransactionNo = transaction_no;
                    order.PayInfo.PayTime = pay_time.ToUnix();
                }
                if (charge.PayInfo.PayChannel == PayChannel.SxyPay)
                    OverSeasMallAccount(charge, ord_htmls);
                else if (charge.PayInfo.PayChannel == PayChannel.H5Pay)
                    H5MallAccount(charge, ord_htmls);
                int result = result = _iUnitOfWork.Commit(buyid.HasValue ? "Orders" + buyid : "");
                return result;
            }
        }

        public Charge MallPaySuccess(pay_html_dto payHtml, string transaction_no, DateTime? pay_time) {
            var charge_dto = payHtml.charge.ToObject<charge_dto>();
            if (charge_dto.status != ChargeStatus.WaitPay)
                throw new ServerErrorException("付款" + charge_dto.order_no + "非待支付状态时", 1002);
            var db_order = context.Charges.FirstOrDefault(c => c.MerchantId == charge_dto.merchant_id && c.PayInfo.PayNo == charge_dto.order_no);
            if (db_order != null && db_order.Status == ChargeStatus.Finish) return null;
            db_order.Status = ChargeStatus.Finish;
            var charge = charge_dto.ToDtoObject<Charge>();
            db_order.PayInfo.TransactionNo = transaction_no;
            db_order.PayInfo.PayTime = pay_time.ToUnix();
            charge.PayId = db_order.PayId;
            charge.OrderTime = db_order.OrderTime;
            var ord_htmls = payHtml.html.ToObject<List<order_dto>>();
            foreach (var ord_html in ord_htmls) {
                var html = ord_html.ToDtoObject<Order>();
                var order = context.Orders.FirstOrDefault(c => c.OrderNo == html.OrderNo);
                if (order.Status != OrderStatus.WaitPay)
                    throw new ServerErrorException("付款" + html.OrderNo + "非待支付状态时", 1002);
                order.Status = OrderStatus.WaitDelivery;
                order.PayInfo.TransactionNo = transaction_no;
                order.PayInfo.PayTime = pay_time.ToUnix();
                if (order.OrderType > 0)
                    order.PushStatus = OrderPushStatus.UnPush;
            }
            return charge;
        }

        public void OverSeasMallAccounts(charge_dto charge, List<order_dto> ord_htmls) {

            lock (dbwaitLock) {
                OverSeasMallAccount(charge.ToDtoObject<Charge>(), ord_htmls);
            }
        }
        /// <summary>
        /// 发货
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ApiResultMessage OrderDelivery(order_model dto) {
            var order = context.Orders.FirstOrDefault(c => c.OrderNo == dto.order_no);
            order.Status = OrderStatus.Confirm;
            int result = _iUnitOfWork.Commit(order.BuyId.HasValue ? "Orders" + order.BuyId : "");
            if (result >= 0)
                return ApiResultToJson.Success("发货成功");
            else
                return ApiResultToJson.Fail("发货失败");
        }

        /// <summary>
        /// 确认收货
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ApiResultMessage OrderReceipt(order_model dto) {
            var order = context.Orders.FirstOrDefault(c => c.OrderNo == dto.order_no);
            order.Status = OrderStatus.Finish;
            order.FinishTime = DateTime.Now.ToUnix();
            //确认收货，解冻账单
            //MallAccountDeblock(order);
            int result = _iUnitOfWork.Commit(order.BuyId.HasValue ? "Orders" + order.BuyId : "");
            if (result >= 0) {
                return ApiResultToJson.Success("确认收货成功");
            } else
                return ApiResultToJson.Fail("确认收货失败");
        }
        /// <summary>
        /// 关闭订单
        /// </summary>
        /// <param name="order_id"></param>
        /// <returns></returns>
        public int CloseOrder(long order_id) {
            var order = context.Orders.FirstOrDefault(c => c.Id == order_id);
            order.Status = OrderStatus.Close;

            int result = _iUnitOfWork.Commit();
            return result;
        }

        /// <summary>
        /// 自动关闭过期没付款的订单
        /// </summary>
        /// <returns></returns>
        public List<order_dto> CloseOrder() {
            var lists = new List<order_dto>();
            try {
                var colse_time = 1;
                var dt = DateTime.Now.AddHours(colse_time).ToUnix();
                var orders = context.Orders.Where(c => c.OrderTime < dt && c.Status == OrderStatus.WaitPay);
                orders.DataForEach(order => {
                    order.Status = OrderStatus.Close;
                });
                int result = _iUnitOfWork.Commit();
                if (result > 0)
                    lists = orders.ToDtoObject<List<order_dto>>();
            } catch (Exception ex) {
                _iUnitOfWork.ErrorLog(ex);
            }
            return lists;
        }
        /// <summary>
        /// 定时确认收货
        /// </summary>
        /// <returns></returns>
        public async Task<int> AutoOrderFinish() {
            int result = 0;
            var tags = new List<string>();
            var merchant = context.Merchants.FirstOrDefault(c => c.MerchantNo == RequestMethod.TOKEN_NO);
            var orders = context.Orders.Where(c => c.Status == OrderStatus.Confirm && (c.MerchantId == merchant.Id || c.Merchant.OemId == merchant.Id)).ToList();
            foreach (var order in orders) {
                if (order.Shipping.ShippingTime.HasValue) {
                    DateTime shippingTime = order.Shipping.ShippingTime.Value.ToDateTime().AddDays(5);
                    if (DateTime.Now >= shippingTime) {
                        if (string.IsNullOrEmpty(order.Shipping.ExpressNo) || string.IsNullOrEmpty(order.Shipping.ShipOrderNumber)) continue;
                        var logistics_result = await _iLogisticsDetailsService.GetLogisticInfo(order.ToDtoObject<order_dto>());
                        if (logistics_result.State == "3") {
                            order.Remark = "系统自动确认收货";
                            order.Status = OrderStatus.Finish;
                            order.FinishTime = shippingTime.ToUnix();
                            if (order.BuyId.HasValue)
                                tags.Add(string.Format("Orders{0}", order.BuyId));
                            result = _iUnitOfWork.Commit(tags.ToArray());
                            System.Threading.Thread.Sleep(600);
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 自动结算账单
        /// </summary>
        public void AutoSettleAccount(long merchant_id = 0) {
            var orders = new List<Order>();
            if (merchant_id > 0)
                orders = context.Orders.Where(c => c.Status == OrderStatus.Finish && c.MerchantId == merchant_id && c.FinishTime.HasValue &&
                                                    (c.OrderSettle == OrderSettleStatus.None || c.OrderSettle == OrderSettleStatus.UnSettle)).ToList();
            else
                orders = context.Orders.Where(c => c.Status == OrderStatus.Finish && c.FinishTime.HasValue &&
                                                    (c.OrderSettle == OrderSettleStatus.None || c.OrderSettle == OrderSettleStatus.UnSettle)).ToList();
            foreach (var order in orders) {
                if (order.FinishTime.HasValue) {
                    var startTime = order.FinishTime.Value.ToDateTime().AddDays(15);
                    if (DateTime.Now >= startTime) {
                        MallAccountDeblock(order);
                        order.Remark = "系统自动进行结算操作";
                        order.OrderSettle = OrderSettleStatus.Settled;
                        //todo:卖家红钻解冻业务
                        var redDrillReceiverId = order.MerchantId;
                        if (order.RedDrillReceiverId.HasValue && order.RedDrillReceiverId.Value > 0)
                            redDrillReceiverId = order.RedDrillReceiverId.Value;
                        if (order.RedDrill > 0)
                            SettleRed(order.BuyId.Value, redDrillReceiverId, order.RedDrill, order.Id);
                        int result = _iUnitOfWork.Commit("RedRecord" + order.BuyId.Value, "RedRecord" + order.MerchantId);
                        System.Threading.Thread.Sleep(100);
                    }
                }
            }
        }
        /// <summary>
        /// 结算红钻
        /// </summary>
        private void SettleRed(long buyId, long sellId, decimal redDrill, long orderId) {
            var sellRedRecord = context.RedRecord.FirstOrDefault(s => s.MerchantId == sellId);
            //解冻卖家获得红钻
            var fRecord = context.RedFrozenRecord.FirstOrDefault(c => c.OrderId == orderId && c.RecordType == 1);
            if (fRecord != null)
                fRecord.Type = 1;
            //卖家卖出商品
            RedRecordDetail sell_detail = new RedRecordDetail();
            sell_detail.MerchantId = sellId;
            sell_detail.HorsePower = 0;
            sell_detail.RedDrill = redDrill;
            sell_detail.Type = 6;
            sell_detail.IsReceive = true;
            sell_detail.ReceiveTime = DateTime.Now.ToUnix();
            sell_detail.CreateTime = DateTime.Now.ToUnix();
            sell_detail.RedProductionTime = 0;
            sell_detail.RedProductionTime = DateTime.Now.ToUnix();
            sell_detail.RedRecordId = sellRedRecord.Id;
            context.RedRecordDetail.Add(sell_detail);
            sellRedRecord.FrozenRedDrill -= redDrill;
            sellRedRecord.TotalRedDrill += redDrill;
        }
        /// <summary>
        /// 红钻退还
        /// </summary>
        /// <param name="buyId">买家id</param>
        /// <param name="sellId">卖家id</param>
        /// <param name="redDrill">红钻值</param>
        /// <param name="orderId">订单id</param>
        private void ReturnRed(long buyId, long sellId, decimal redDrill, long orderId) {
            if (redDrill == 0)
                return;
            var buyRedRecord = context.RedRecord.FirstOrDefault(s => s.MerchantId == buyId);
            var sellRedRecord = context.RedRecord.FirstOrDefault(s => s.MerchantId == sellId);
            //买家退还红钻
            RedRecordDetail buy_detail = new RedRecordDetail();
            buy_detail.MerchantId = buyRedRecord.MerchantId;
            buy_detail.HorsePower = 0;
            buy_detail.RedDrill = redDrill;
            buy_detail.Type = 8;
            buy_detail.IsReceive = true;
            buy_detail.ReceiveTime = DateTime.Now.ToUnix();
            buy_detail.CreateTime = DateTime.Now.ToUnix();
            buy_detail.RedProductionTime = 0;
            buy_detail.RedRecordId = buyRedRecord.Id;
            //解冻卖家获得红钻
            RedFrozenRecord fRecord = new RedFrozenRecord();
            fRecord.MerchantId = sellId;
            fRecord.OrderId = orderId;
            fRecord.RedDrill = redDrill;
            fRecord.RecordType = 1;
            fRecord.Type = 1;
            fRecord.CreateTime = DateTime.Now.ToUnix();
            context.RedRecordDetail.Add(buy_detail);
            context.RedFrozenRecord.Add(fRecord);
            buyRedRecord.ConsumeRedDrill -= redDrill;
            sellRedRecord.FrozenRedDrill -= redDrill;//卖家增加解冻红钻
        }
        /// <summary>
        /// 增加人工自动结算业务
        /// </summary>
        /// <param name="orderNo"></param>
        public void AutoSettleAccount(string orderNo) {
            var order = context.Orders.FirstOrDefault(c => c.OrderNo == orderNo);
            if (order != null) {
                MallAccountDeblock(order);
                order.Remark = "系统自动进行结算操作";
                order.OrderSettle = OrderSettleStatus.Settled;
                int result = _iUnitOfWork.Commit();
            }
        }
        public sxy_customs_result_base CustomsPush(sxy_customs_push model) {
            var resultApi = _sxyPaySign.PayGateway<sxy_customs_result_base>(model, "/jiaofei/CrossTrade_OrderSend.jsp").Result;
            return resultApi;
        }

        public sxy_customs_result_base CustomsQuery(sxy_customs_query model) {
            var resultApi = _sxyPaySign.PayGateway<sxy_customs_query_result>(model, "/jiaofei/CrossTrade_OrderQuery.jsp").Result;
            return resultApi;
        }
        public int UpdateOrderItem(long id, List<order_item_dto> list) {
            int result = -1;
            if (list != null && list.Count > 0) {
                foreach (var item in list) {
                    var model = context.OrderItems.FindById(item.id);
                    if (model != null) {
                        model.LegalWeight = item.legalweight;
                        model.GrossWeight = item.grossweight;
                        result = context.SaveChanges();

                    }
                }
            }
            return result;
            //    List<OrderItem> list2 = new List<OrderItem>();
            //    Order order = this.context.Orders.FindById(id);
            //    list.ToDtoObject(list2);

            //    foreach (OrderItem current in list2)
            //    {
            //        bool flag = current.SkuPath == null;
            //        if (flag)
            //        {
            //            current.SkuPath = "";
            //        }
            //    }
            //    order.OrderItems = list2;
            //    return this._iUnitOfWork.Commit("OrderItem");
        }
        /// <summary>
        /// 跟新订单状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="orderStatus"></param>
        /// <returns></returns>
        public int Update(long id, OrderStatus orderStatus, string transaction_no) {
            int result = -1;
            #region 如果订单状态是待付款
            if (orderStatus == OrderStatus.WaitPay) {
                var payinfo = context.PayInfos.Where(x => x.Id == id).FirstOrDefault();
                if (payinfo != null) {
                    payinfo.PayTime = DateTime.Now.ToUnix();
                    payinfo.TransactionNo = transaction_no;
                    var buyid = context.Orders.FirstOrDefault(x => x.PayId == id).BuyId;
                    result = _iUnitOfWork.Commit(buyid.HasValue ? "Orders" + buyid : "");
                }
            } else {
                #region 修改订单状态
                var list = context.Orders.Where(x => x.PayId == id).ToList();
                var buyid = list.FirstOrDefault().BuyId;
                list.DataForEach(item => {
                    item.Status = orderStatus;
                });
                result = _iUnitOfWork.Commit(buyid.HasValue ? "Orders" + buyid : "");
                #endregion
            }
            #endregion
            return result;
        }

        /// <summary>
        /// 生成订单xml报文
        /// </summary>
        /// <param name="pay_id">Pay identifier.</param>
        public string CreateOrderXml(long pay_id) {
            var orders = context.Orders.Where(c => c.PayId == pay_id);
            var order_first = orders.First();
            var payInfo = order_first.PayInfo;
            var shipping = order_first.Shipping;
            decimal amount = 0;
            decimal payAmount = orders.Sum(c => c.PayAmount);
            decimal freight = orders.Sum(c => c.Freight);
            orders.First().OrderItems.ForEach(c => {
                amount += (decimal)c.UnitPrice * (decimal)c.Quantity;
            });

            CEB311Message cEB311Message = new CEB311Message();
            cEB311Message.Order.OrderHead = new OrderHead {
                orderNo = payInfo.OrderNo,
                goodsValue = amount,
                freight = freight,
                discount = 0,
                taxTotal = (decimal)order_first.Tax,
                acturalPaid = payAmount,
                buyerRegNo = order_first.Buyer.Mobile,
                buyerIdNumber = order_first.Shipping.IdCard,
                buyerName = order_first.Shipping.RealName,
                buyerIdType = "1",
                payTransactionId = payInfo.TransactionNo,
                consignee = shipping.RealName,
                consigneeTelephone = shipping.Phone,
                consigneeAddress = shipping.RegionName.Replace(" ", "") + shipping.Address,
                consigneeDistrict = shipping.RegionId.ToString(),
                consigneeIdNumber = shipping.IdCard,
                batchNumbers = " ",
                note = " "
            };
            string txtPwd = "fa0c7a02-dd66-4ff9-9556-14a4515db57e" + cEB311Message.Order.OrderHead.ebcCode + payInfo.OrderNo + cEB311Message.Order.OrderHead.appTime;
            cEB311Message.Order.OrderHead.applyKey = SecureHelper.MD5(txtPwd);
            int index = 1;
            _iUnitOfWork.Commit("Product");
            foreach (var order in orders) {
                foreach (var item in order.OrderItems) {
                    cEB311Message.Order.OrderList.Add(new OrderList {
                        gnum = index,
                        itemDescribe = " ",
                        itemNo = item.Product.Code,
                        //itemNo = item.Product.GoodDeclaration.Barcode,
                        //itemName = item.ProductName,
                        itemName = item.Product.GoodDeclaration.GoodName,
                        barCode = item.Product.GoodDeclaration.Barcode,
                        unit = item.Product.Unit,
                        qty = item.Quantity,
                        price = item.UnitPrice,
                        totalPrice = item.Quantity * item.UnitPrice,
                        country = "143",//台澎金马关税区
                        goodsRegNoCiq = item.Product.GoodDeclaration.FileCode,
                        wrapTypeCiq = "4M",
                        note = " "
                    });
                    index++;
                }
            }

            string path = CommonHelper.MapPath(string.Format("{0}/CEB311Message_{1}_v{2}.xml", "~/ceb", payInfo.OrderNo, DateTime.Now.ToString("yyyyMMdd")));
            string xml = XmlHelper.XmlSerialize(cEB311Message, Encoding.UTF8);
            XmlHelper.XmlSave(xml, path);
            return path;
        }
        /// <summary>
        /// 向海关推送订单报文
        /// </summary>
        /// <returns><c>true</c>, if order xml was pushed, <c>false</c> otherwise.</returns>
        /// <param name="path">Path.</param>
        public bool PushOrderXml(string path) {
            string msg = string.Empty;
            var result = FtpHelper.GetInstance().Upload(RequestMethod.FTP_ACCOUNT, RequestMethod.FTP_PASSWORD, path, RequestMethod.FTP_UPLOAD_PATH, out msg);
            return result;
        }
        public int Add(order_dto dto) {
            Order model = new Order();
            dto.ToDtoObject(model);
            context.Orders.Add(model);
            int result = _iUnitOfWork.Commit(model.BuyId.HasValue ? "Orders" + model.BuyId : "");
            dto.id = model.Id;
            return result;
        }
        public int Delete(long Id) {
            var model = context.Orders.Where(x => x.Id == Id).FirstOrDefault();
            context.OrderItems.RemoveRange(model.OrderItems);
            context.PayInfos.Remove(model.PayInfo);
            context.Orders.Remove(model);
            int result = _iUnitOfWork.Commit(model.BuyId.HasValue ? "Orders" + model.BuyId : "");
            return result;
        }

        /// <summary>
        /// 跨境电商发货
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int OrderDelivery(long id) {
            var orders = context.Orders.Where(c => c.PayId == id).ToList();
            var buyid = orders.FirstOrDefault().BuyId;
            var logitics_no = context.LogisticsNO.FirstOrDefault(c => c.LogisticsStatus == 1);
            foreach (var item in orders) {
                item.Shipping.ShipOrderNumber = logitics_no.LogisticsNumber;
                item.Status = OrderStatus.Confirm;
            }
            logitics_no.LogisticsStatus = 2;
            var result = _iUnitOfWork.Commit(buyid.HasValue ? "Orders" + buyid : "");
            return result;
        }

        /// <summary>
        /// 发货
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public int OrderDelivery(order_dto_ex dto) {
            var model = context.Orders.FirstOrDefault(c => c.OrderNo == dto.order_no);
            model.Shipping.ExpressNo = dto.express_no;
            model.Shipping.ExpressCompanyName = dto.express_company_name;
            model.Shipping.ShipOrderNumber = dto.ship_order_number;
            model.Shipping.ShippingTime = DateTime.Now.ToUnix();
            model.Status = OrderStatus.Confirm;
            if (model.PushStatus == OrderPushStatus.PushFail && (model.OrderType == 1 || model.OrderType == 2)) {
                model.PushStatus = OrderPushStatus.Pushed;
                model.PushFailMsg = "推送成功";
            }
            var msg = _iSettingService.Get().msg.FirstOrDefault(c => c.code == "order_delivery");
            if (msg == null)
                throw new ServerErrorException("发货消息未配置");
            var buyerMessage = new MessagePush();
            var mobiles = new List<string>();
            string product_name = model.OrderItems.First().ProductName;
            if (model.BuyId > 0) {
                mobiles.Add(model.Buyer.Mobile);
                buyerMessage.MerchantId = model.BuyId.Value;
                buyerMessage.Type = MsgType.OrderSellerDeliver;
                buyerMessage.Title = msg.name;
                buyerMessage.ShortContent = string.Format(msg.content, product_name, dto.ship_order_number);
                buyerMessage.Content = string.Format(msg.content, product_name, dto.ship_order_number);
                buyerMessage.Ext = "{}";
                buyerMessage.CreateTime = DateTime.Now.ToUnix();
                buyerMessage.ObjectId = model.Id;
                context.MessagePushs.Add(buyerMessage);
                //if (model.ShopId > 0) {
                //    var shopinfo = context.ShopInfo.FirstOrDefault(c => c.Id == model.ShopId);
                //    var message = new MessagePush();
                //    buyerMessage.ToCopyProperty(message);
                //    message.MerchantId = shopinfo.Id;
                //    message.ObjectId = shopinfo.Id;
                //    message.Url = "";
                //    context.MessagePushs.Add(message);
                //    mobiles.Add(shopinfo.Merchant.Mobile);
                //}
            }
            product_name = (product_name.Length > 7 ? product_name.Substring(0, 7) + "..." : product_name);
            msg.content = string.Format(msg.content, product_name, dto.ship_order_number);
            _iSettingService.SendTokenSms(model.Shipping.Phone, msg.content);
            int result = _iUnitOfWork.Commit(model.BuyId.HasValue ? "Orders" + model.BuyId : "");
            if (result > 0 && model.BuyId > 0) {
                JPushHelp jPushHelp = new JPushHelp(t_RequestMethod.push_app_key, t_RequestMethod.push_app_secret);
                jPushHelp.Push(buyerMessage.Title, buyerMessage.Content, (int)buyerMessage.Type, buyerMessage.ObjectId.Value, mobiles);
            }
            return result;
        }

        /// <summary>
        /// 确认订单
        /// </summary>
        /// <returns>The out.</returns>
        /// <param name="model">Model.</param>
        /// <param name="isSeaOver">If set to <c>true</c> is sea over.</param>
        public List<order_dto> CheckOut(CartModel model, out bool isSeaOver) {
            bool any_address = false;
            long? distribute_id = 0;
            decimal total_money = 0;
            isSeaOver = false;
            var products = new List<product_dto>();
            foreach (var cart_model in model.ordermodel) {
                var product = _iProductService.Get(cart_model.productid);
                var sku = product.product_skus.FirstOrDefault(s => s.id == cart_model.skuid);
                decimal price = (sku == null ? product.price : sku.price);
                total_money += price;
                var merchant = _iMerchantService.Get(cart_model.merchantid);
                //if (entrepot_id == 0)
                //    entrepot_id = merchant.entrepot_id;
                //if (entrepot_id != merchant.entrepot_id)
                //    any_address = true;
                cart_model.name = product.name;
                cart_model.price = price;
                products.Add(product);
                isSeaOver = product.is_seas;
            }
            var productGroups = products.GroupBy(p => p.is_seas);
            if (productGroups.Count() >= 2)
                throw new ServerErrorException("不能混合购买海外和大陆产品");

            if (any_address)
                throw new ServerErrorException("有多个集散地");
            if (total_money > 2000)
                throw new ServerErrorException("订单总金额不能超过¥2000元");

            object object_id = model.user_id > 0 ? model.user_id.ToString() : model.cache_no;
            var orders = GetOrderList(object_id);
            if (orders == null) {
                if (!string.IsNullOrEmpty(model.share_no)) {
                    var merchant = _iMerchantService.Get(model.share_no);
                    if (merchant == null)
                        throw new ServerErrorException("非法用户");
                    distribute_id = merchant.id;
                }

                orders = new List<order_dto>();
                var groups = model.ordermodel.GroupBy(c => new {
                    c.merchantid
                });
                foreach (var rows in groups) {
                    var paymodel = new order_dto();
                    decimal seller_amount = 0;//卖家实收金额【货款】
                    decimal tax = 0;
                    double sum_weight = 0;
                    var items = new List<order_item_dto>();
                    foreach (var cart in rows) {
                        var product = _iProductService.Get(cart.productid);
                        var sku = product.product_skus.FirstOrDefault(c => c.id == cart.skuid);

                        var item = new order_item_dto {
                            product = product,
                            product_id = product.id,
                            product_name = product.name,
                            quantity = cart.quantity,
                            thumbnails_url = product.first_image,
                            unit_price = product.price,
                            market_price = product.market_price,
                            sku_path = (sku == null ? "" : sku.sku_path),
                            sku_name = (sku == null ? "" : sku.sku_name)
                        };
                        if (product.cost_price > 0) {
                            var dics = new Dictionary<string, object>();
                            dics.Add("cost_price", product.cost_price);
                            item.body = dics;
                        }
                        //卖家实收
                        decimal cost_price = product.cost_price.HasValue ? product.cost_price.Value : 0;
                        seller_amount += (cost_price - cost_price * 0.12M) * cart.quantity;
                        tax = product.tax ?? 0;
                        sum_weight += product.weight * cart.quantity;
                        items.Add(item);
                    }
                    decimal goods_price = items.Sum(c => c.quantity * c.unit_price);
                    double freight = calculateFreight(sum_weight);
                    tax = calculateTax(tax, goods_price, freight);
                    paymodel.distribution_id = distribute_id;
                    paymodel.order_amount = goods_price + (decimal)freight + (decimal)tax;
                    paymodel.amount = seller_amount;
                    paymodel.disAmount = items.Sum(c => (c.unit_price - c.product.cost_price ?? 0) * c.quantity);
                    paymodel.order_items = items;
                    paymodel.order_no = DtoHelper.GenerateOrderNumber();
                    paymodel.order_time = DateTime.Now;
                    paymodel.freight = (decimal)freight;
                    paymodel.tax = tax;
                    //买家实付金额
                    paymodel.pay_amount = paymodel.order_amount - paymodel.discount_amount - paymodel.integral_discount;
                    if (model.user_id > 0) {
                        paymodel.buy_id = model.user_id;
                        var shipAddress = _iShippAddressService.GetByDefault(paymodel.buy_id.Value);
                        if (shipAddress != null) {
                            paymodel.shipping = new shipping_dto {
                                address = shipAddress.address,
                                region_id = (shipAddress.area_id == 0 ? shipAddress.city_id : shipAddress.area_id),
                                phone = shipAddress.phone,
                                region_name = shipAddress.region_name,
                                ship_to = shipAddress.ship_to,
                                real_name = shipAddress.real_name,
                                id_card = shipAddress.id_card,
                                card_negative = shipAddress.card_negative,
                                card_positive = shipAddress.card_positive
                            };
                        }
                    }
                    orders.Add(paymodel);
                }
                SetOrderList(orders, object_id);
            }

            return orders;
        }

        /// <summary>
        /// /计算运费
        /// </summary>
        /// <returns>The freight.</returns>
        /// <param name="product_weight">Product weight.</param>
        private double calculateFreight(double product_weight) {
            double freight = 0;
            freight = Math.Ceiling(product_weight) * _iSettingService.GetGlb().overseas.user_cost;
            return freight;
        }
        /// <summary>
        /// 计算税费
        /// </summary>
        /// <returns>The tax.</returns>
        /// <param name="tax_value">Tax value.</param>
        /// <param name="goods_price">Unit price.</param>
        /// <param name="freight">Freight.</param>
        private decimal calculateTax(decimal tax_value, decimal goods_price, double freight) {
            decimal tax = 0;
            tax = ((goods_price + (decimal)freight) * (tax_value / 100)).RoundUp(2);
            return tax;
        }
        /// <summary>
        /// 获取支付订单
        /// </summary>
        /// <returns>The out pay.</returns>
        /// <param name="model">Model.</param>
        /// <param name="object_id">Object identifier.</param>
        public mall_model CheckOutPay(CartPayModel model, out object object_id) {
            var orderlist = new List<order_dto>();
            //正常购买已UserID为key取缓存，匿名购买和待支付业务已pay_no为key取缓存。
            object_id = (string.IsNullOrEmpty(model.pay_no) ? model.user_id.ToString() : model.pay_no);
            if (model.user_id > 0 && !string.IsNullOrEmpty(model.pay_no)) {
                orderlist = GetOrdersByOrderNo(model.pay_no);
            } else {
                orderlist = GetOrderList(object_id);
                if (orderlist == null)
                    throw new ServerErrorException("缓存数据失效");
            }

            bool is_seaover = false;
            foreach (var item in orderlist) {
                item.binds = GetProfits(item, model);
                var order_item = item.order_items.FirstOrDefault();
                var product = _iProductService.Get(order_item.product_id);
                is_seaover = product.is_seas;
            }

            var order = orderlist.FirstOrDefault();
            var mall = new mall_model();
            if (order.buy_id.HasValue) {
                var merchant = _iMerchantService.Get(order.buy_id.Value);
                mall.bind_no = merchant.merchant_no;
            }
            mall.pay_channel = is_seaover ? PayChannel.SxyPay : PayChannel.H5Pay;
            mall.req_method = 2;
            mall.body = order.order_items.FirstOrDefault().product_name;
            mall.notify = model.notify;
            mall.front_notify = model.front_notify;
            mall.orders = orderlist;
            mall.merchant_no = model.merchant_no;
            mall.method = model.method;
            mall.nonce = DtoHelper.RandCode(10);
            mall.order_no = DtoHelper.GenerateOrderNumber();
            mall.pay_code = is_seaover ? "GATEWAY" : "H5Pay";
            mall.settle_type = "T1";
            mall.openid = model.ip;
            if (order.shipping != null) {
                var regionlist = _iRegionService.GetParents(order.shipping.region_id).ToList();
                mall.shipping = new shipping_model {
                    address = order.shipping.address,
                    id_card = order.shipping.id_card,
                    real_name = order.shipping.real_name,
                    area_id = regionlist.Count == 3 ? regionlist[2].id : 0,
                    city_id = regionlist[1].id,
                    phone = order.shipping.phone,
                    province_id = regionlist[0].id,
                    region_name = order.shipping.region_name,
                    ship_to = order.shipping.ship_to
                };
            }

            mall.shipping_type = 1;
            mall.subject = "快捷支付";
            mall.timestamp = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            mall.tran_amount = (Math.Round(orderlist.Sum(x => x.order_amount) * 100, 2)).ToString();
            return mall;
        }

        /// <summary>
        /// 分润计算
        /// </summary>
        /// <returns>The profits.</returns>
        /// <param name="order">Order.</param>
        private List<bind_merchant_item> GetProfits(order_dto order, CartPayModel model) {
            var binds = new List<bind_merchant_item>();
            if (!order.buy_id.HasValue && order.distribution_id == 0)
                return binds;
            var merchant_id = ((order.distribution_id.HasValue && order.distribution_id > 0) ? order.distribution_id.Value : order.buy_id.Value);
            foreach (var item in order.order_items) {
                var profits = CalculProfits(item, merchant_id, model);
                binds.AddRange(profits);
            }
            return binds;
        }

        private List<bind_merchant_item> CalculProfits(order_item_dto order_item, long merchant_id, CartPayModel model) {
            var log = new LogHelper("info");
            var binds = new List<bind_merchant_item>();
            bool is_exist = false;
            //成本价
            decimal price = (order_item.body.Count > 0 ? Convert.ToDecimal(order_item.body["cost_price"]) : 0);
            //分销利润
            decimal amount = (order_item.unit_price - price) * order_item.quantity;
            amount = amount - amount * 0.15M;
            var parents = _iMerchantService.GetParents(merchant_id);
            foreach (var parent in parents) {
                var merchant = _iMerchantService.Get(parent.id);
                var grade = _iGradeService.Get(merchant.grade_id ?? 0);
                //vip获取利润
                if (grade.grade_no == model.user_level_vip && !is_exist) {
                    binds.Add(new bind_merchant_item {
                        merchant_no = merchant.merchant_no,
                        product_id = order_item.product_id,
                        product_name = order_item.product_name,
                        amount = amount * 0.5M
                    });
                    is_exist = true;
                }
                //招商获取利润
                if (grade.grade_no == model.user_level_top) {
                    decimal fee = binds.Count > 0 ? 0.1M : 0.6M;
                    binds.Add(new bind_merchant_item {
                        merchant_no = merchant.merchant_no,
                        product_id = order_item.product_id,
                        product_name = order_item.product_name,
                        amount = amount * fee
                    });
                    break;
                }
            }
            //平台毛利
            binds.Add(new bind_merchant_item {
                product_id = order_item.product_id,
                product_name = order_item.product_name,
                amount = price * order_item.quantity * 0.12M + amount - binds.Sum(c => c.amount),
                is_plat = true
            });
            log.Info(binds.ToJson());
            return binds;
        }

        public List<order_dto> GetOrderList(object object_id) {
            string key = string.Format("Cart-{0}", object_id);
            var result = _iUnitOfWork.GetCache<List<order_dto>>(key);
            if (result == null) return new List<order_dto>();
            return result;
        }
        public void SetOrderList(List<order_dto> list, object object_id) {
            string key = string.Format("Cart-{0}", object_id);
            _iUnitOfWork.SetCache(key, list, 600);
        }
        public void ClearOrderList(object object_id) {
            string key = string.Format("Cart-{0}", object_id);
            _iUnitOfWork.RomoveCache(key);
        }

        #region 拓垦商城
        public void SetOrderModelCache(token_mall_confirm_order_model model, string key) {
            key = string.Format("token_mall_order_{0}", key);
            _iUnitOfWork.SetCache(key, model, 600);
        }
        public token_mall_confirm_order_model GetOrderModelCache(string key) {
            key = string.Format("token_mall_order_{0}", key);
            var result = _iUnitOfWork.GetCache<token_mall_confirm_order_model>(key);
            return result;
        }
        public void ClearOrderModelCache(string key) {
            key = string.Format("token_mall_order_{0}", key);
            _iUnitOfWork.RomoveCache(key);
        }

        /// <summary>
        /// 临时业务算法规格
        /// </summary>
        /// <param name="order"></param>
        /// <param name="merchant_no"></param>
        /// <returns></returns>
        private List<bind_merchant_item> GetProfits(order_dto order, string merchant_no) {
            var binds = new List<bind_merchant_item>();
            var order_item = order.order_items.First();
            var product = _iProductService.Get(order_item.product_id);
            if (string.IsNullOrEmpty(merchant_no) || !product.is_open)
                return binds;
            var amount = product.distribution_price.HasValue ? product.distribution_price.Value * order_item.quantity : 0;
            binds.Add(new bind_merchant_item {
                merchant_no = merchant_no,
                amount = amount,
                product_id = product.id,
                product_name = product.name,
                freeze = true
            });
            return binds;
        }
        /// <summary>
        /// 删除拓垦商城订单
        /// </summary>
        /// <returns></returns>
        public int DeleteOrder(long id) {
            var model = context.Orders.FindById(id);
            model.IsBuyDel = true;
            return _iUnitOfWork.Commit(model.BuyId.HasValue ? "Orders" + model.BuyId : "");
        }

        /// <summary>
        /// 确认收货
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int ConfirmOrder(long id) {
            var model = context.Orders.FindById(id);
            model.Status = OrderStatus.Finish;
            model.FinishTime = DateTime.Now.ToUnix();
            return _iUnitOfWork.Commit(model.BuyId.HasValue ? "Orders" + model.BuyId : "");
        }
        /// <summary>
        /// 后台人工确认收货
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int HandConfirmOrder(long id) {
            var order = context.Orders.FindById(id);
            if (order.Status == OrderStatus.Confirm) {
                order.Status = OrderStatus.Finish;
                order.FinishTime = order.OrderTime.ToDateTime().AddDays(5).ToUnix();
            }
            return _iUnitOfWork.Commit(order.BuyId.HasValue ? "Orders" + order.BuyId : "");
        }
        public int StopAutoOrder(long id) {
            var order = context.Orders.FindById(id);
            if (order.PushStatus != OrderPushStatus.PushForbid) {
                order.PushStatus = OrderPushStatus.PushForbid;
                order.PushFailMsg = "停止自动推单";
            }
            return _iUnitOfWork.Commit(order.BuyId.HasValue ? "Orders" + order.BuyId : "");
        }
        /// <summary>
        /// 更新订单状态
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public string UpdateShipping(htl_orders_info_res res) {
            DateTime dt = DateTime.Now;
            List<string> buyids = new List<string>();
            foreach (var order_info in res.orders_info.order) {
                if ((order_info.orders_status == "已发货" && order_info.orders_status_code == "9") || order_info.orders_status == "已出库" && order_info.orders_status_code == "23") {
                    var order = context.Orders.FirstOrDefault(c => c.OrderNo == order_info.custom_orders_number);
                    order.Status = OrderStatus.Confirm;
                    DateTime.TryParse(order_info.gmt_modified, out dt);
                    order.Shipping.ShippingTime = dt.ToUnix();
                    if (order.BuyId.HasValue && !buyids.Contains("Orders" + order.BuyId.Value.ToString()))
                        buyids.Add("Orders" + order.BuyId.Value.ToString());
                }
            }
            int result = _iUnitOfWork.Commit(buyids.ToArray());
            return (result > 0 ? "ok" : "fail");
        }
        /// <summary>
        /// 生成退款/退货单
        /// </summary>
        /// <param name="dto"></param>
        public void CreateOrderRefund(order_refund_dto dto) {
            var date_time = DateTime.Now.ToUnix();
            dto.order_refund_no = DtoHelper.GenerateOrderNumber();
            var order_refund = dto.ToDtoObject<OrderRefund>();
            order_refund.Status = OrderRefundStatus.Handle;
            order_refund.CreateTime = date_time;
            order_refund.HandleTime = date_time;
            context.OrderRefund.Add(order_refund);
        }

        #endregion

        #region 退款/退货

        public int OrderRefund(order_refund_dto order_refund) {
            var order = context.Orders.FirstOrDefault(c => c.Id == order_refund.order_id);
            if (order == null)
                throw new ServerErrorException("找不到该订单号");
            if (order.PayAmount == 0) {
                if (order_refund.amount < 0)
                    throw new ServerErrorException("退款/退货金额不能小于0");
            } else {
                if (order_refund.amount <= 0)
                    throw new ServerErrorException("退款/退货金额大于0");
            }
            if (string.IsNullOrEmpty(order_refund.remark))
                throw new ServerErrorException("请填写退款/退货理由");
            if (order_refund.amount > order.PayAmount)
                throw new ServerErrorException("退款/退货金额不能大于货款金额");
            if (order.OrderType == 3)
                throw new ServerErrorException("该订单不支持退款/退货操作");
            if (order.FinishTime.HasValue) {
                var finishTime = order.FinishTime.Value.ToDateTime();
                if (DateTime.Now >= finishTime.AddDays(15))
                    throw new ServerErrorException("该订单已完成，不允许进行退款、退货操作。");
            }
            bool is_finish = context.OrderRefund.Exist(c => c.OrderId == order_refund.order_id);
            if (is_finish)
                throw new ServerErrorException("该订单已退款");
            order.Status = OrderStatus.Close;
            order.PushStatus = OrderPushStatus.Pushed;
            order.PushFailMsg = "该笔订单已退款";
            //创建退款单
            CreateOrderRefund(order_refund);
            //分润表退货款和一级/二级分润
            MallRefundAccount(order.Id, order_refund.amount);
            //如果该订单是红钻兑换或现金+红钻兑换业务，退款卖家需返还冻结红钻。
            ReturnRed(order.BuyId.Value, order.MerchantId, order.RedDrill, order.Id);
            return _iUnitOfWork.Commit("RedRecord" + order.BuyId.Value, "RedRecord" + order.MerchantId);
        }

        #endregion
        /// <summary>
        /// 立即购买 购物车购买
        /// </summary>
        /// <param name="cartModel"></param>
        /// <param name="type">0 立即购买 1 购物车</param>
        /// <returns></returns>
        public token_check_out_model AddBuy(List<AddCartModel> cartModel, int type) {
            if (cartModel.Count == 0) throw new ServerErrorException("请选择商品");
            var shopids = cartModel.Select(s => s.shop_id).Distinct().ToList();
            var productids = cartModel.Select(s => s.product_id).ToList();
            var shops = context.ShopInfo.Where(s => shopids.Contains(s.Id)).ToList();
            var products = context.Products.Where(s => productids.Contains(s.Id)).ToList().ToDtoList<product_dto>();
            token_check_out_model model = new token_check_out_model { source_type = type };
            model.orders = new List<token_order_model>();
            var data = cartModel.GroupBy(s => s.shop_id).ToList();
            foreach (var list in data) {
                var shop = shops.FirstOrDefault(s => s.Id == list.Key);
                token_order_model order_model = new token_order_model() { shop_id = list.Key, shop_logo = shop == null ? "" : shop.ShopLogo, shop_name = shop == null ? "" : shop.ShopName };
                order_model.order_items = new List<token_order_item_model>();
                foreach (var item in list) {
                    var product = products.FirstOrDefault(s => s.id == item.product_id);
                    product = _iProductActivityService.ProductActivityHandle(product);
                    product_sku_dto sku = null;
                    if (product == null) { throw new ServerErrorException("商品已失效"); }
                    if (!(product.sale_status == SaleStatus.Sell && (product.audit_status == AuditStatus.Sell || product.audit_status == AuditStatus.PendingAudit))) {
                        throw new ServerErrorException("商品" + product.name + "已失效");
                    }
                    if (item.sku_id > 0) {
                        sku = product.product_skus.FirstOrDefault(s => s.id == item.sku_id);
                        if (sku == null) { throw new ServerErrorException("商品" + product.name + "已失效"); }
                        if (sku.stock < item.num) { throw new ServerErrorException("商品" + product.name + "库存不足"); }
                    } else {
                        if (product.stock < item.num) { throw new ServerErrorException("商品" + product.name + "库存不足"); }
                    }
                    token_order_item_model order_item = new token_order_item_model() { price = product.price, product_main_img = product.first_image, num = item.num, product_id = product.id, product_name = product.name, sku_id = item.sku_id, share_no = item.merchant_no, sku_name = sku == null ? "" : sku.sku_name };
                    order_model.order_items.Add(order_item);
                }
                model.orders.Add(order_model);
            }
            return model;
        }
        public mall_model GetTokenMallPayOrder(token_check_out_model model) {
            var orders = new List<order_dto>();
          var member=  _iMerchantService.Get(model.buy_user_id);
            if (!model.is_cash_pay ) {
                if (!member.is_face) {
                    throw new ServerErrorException("您未完成人脸认证！请您到\"我的\"-\"设置\"进行人脸认证。");
                }
               
            }
            var mall = new mall_model { order_no = DtoHelper.GenerateOrderNumber(), source_type = model.source_type };
            foreach (var order in model.orders) {
                if (!string.IsNullOrEmpty(order.order_no)) {
                    var order_dto = context.Orders.FirstOrDefault(c => c.OrderNo == order.order_no).ToDtoObject<order_dto>();
                    if (order_dto != null && order_dto.shipping != null) {
                        var regionlist1 = _iRegionService.GetParents(order_dto.shipping.region_id).ToList();
                        mall.shipping = new shipping_model {
                            address = order_dto.shipping.address,
                            id_card = order_dto.shipping.id_card,
                            real_name = order_dto.shipping.real_name,
                            area_id = regionlist1.Count == 3 ? regionlist1[2].id : 0,
                            city_id = regionlist1[1].id,
                            phone = order_dto.shipping.phone,
                            province_id = regionlist1[0].id,
                            region_name = order_dto.shipping.region_name,
                            ship_to = order_dto.shipping.ship_to
                        };
                    }
                    model.total_amount += order_dto.pay_amount;
                    order_dto.buyer = null;
                    order_dto.merchant = null;
                    order_dto.pay_info.orders = null;
                    if (order_dto.distribution_id.HasValue) {
                        var merchant = _iMerchantService.Get(order_dto.distribution_id.Value);
                        if (merchant != null) {
                            order_dto.dis_user = merchant;
                        }
                    }
                    order_dto.order_items.ForEach(c => {
                        var product_ex = _iProductService.GetCalculateExForActivity(c.product_id, c.sku_id ?? 0, model.is_cash_pay);
                        if (c.product_activity_id != product_ex.product_activity_id || product_ex.price != c.unit_price) {
                            throw new ServerErrorException("产品信息已发生变更，请重新下单");
                        }
                        if (product_ex.stock < c.quantity)
                            throw new ServerErrorException(string.Format("商品：{0}，库存不足", c.product_name));
                        if (c.distribution_id.HasValue && c.distribution_id.Value > 0) {
                            var merchant = _iMerchantService.Get(order_dto.distribution_id.Value);
                            if (merchant != null) {
                                c.dis_user = merchant;
                            }
                        }
                    });
                    orders.Add(order_dto);
                    var record = _iRedRecordService.GetUser(order_dto.buy_id.Value);
                    if (record != null) {
                        if (record.present_red_drill < order_dto.red_drill)
                            throw new ServerErrorException("您购买该商品红钻不足，请重新下单");
                    }
                } else {
                    var ord = new order_dto {
                        order_no = DtoHelper.GenerateOrderNumber(),
                        status = OrderStatus.WaitPay,
                        order_time = DateTime.Now,
                        buy_id = model.buy_user_id,
                        freight = order.freight,
                        merchant_id = order.shop_id,
                        remark = order.remark
                    };
                    decimal order_amount = 0, disAmount = 0, drillAmount = 0;
                    foreach (var item in order.order_items) {
                        if (!model.is_cash_pay)
                            item.price = item.activity_price;
                        var product_ex = _iProductService.GetCalculateExForActivity(item.product_id, item.sku_id, true, model.is_cash_pay);//包含预热，并判断商品是否在预热期内
                        if (product_ex == null)
                            throw new ServerErrorException(string.Format("商品：{0}，不存在或已下架", item.product_name));
                        if ((product_ex.begin_time != null && product_ex.preheat_time != null) && DateTime.Now >= product_ex.preheat_time && DateTime.Now <= product_ex.begin_time)
                            throw new ServerErrorException(string.Format("商品：{0}，活动即将开始", item.product_name));
                        if (product_ex.is_sold_out == true)
                            throw new ServerErrorException(string.Format("商品：{0}，已售罄", item.product_name));
                        if (product_ex.stock <= 0)
                            throw new ServerErrorException(string.Format("商品：{0}，已售罄", item.product_name));
                        if (!product_ex.is_sale)
                            throw new ServerErrorException(string.Format("商品：{0}，已下架", item.product_name));
                        if (product_ex.price != item.price)
                            throw new ServerErrorException(string.Format("商品：{0}，价格已变更", item.product_name));
                        if (product_ex.activity_red_drill != item.red_drill)
                            throw new ServerErrorException(string.Format("商品：{0}，价格（红钻）已变更", item.product_name));
                        if (product_ex.stock < item.num)
                            throw new ServerErrorException(string.Format("商品：{0}，库存不足", item.product_name));
                        if (product_ex.max_quantity > 0 && item.num > product_ex.max_quantity)
                            throw new ServerErrorException(string.Format("商品：{0}，最大购买数量为：{1} 件", item.product_name, product_ex.max_quantity));
                        if (product_ex.activity_type == 4 && product_ex.max_quantity > 0) {//红钻兑换活动，判断每人最大购买数量
                            List<OrderItem> orderItems = context.OrderItems.Where(o => o.Order.BuyId == model.buy_user_id && o.ProductId == item.product_id &&
                            o.ProductActivityId == product_ex.product_activity_id &&
                            o.Order.Status != OrderStatus.Close && ((item.sku_id == 0 && o.SkuId == null) || (o.SkuId == item.sku_id))).ToList() ?? new List<OrderItem>();
                            if (item.num + orderItems.Sum(o => o.Quantity) > product_ex.max_quantity) {
                                if (orderItems.Exists(o => o.Order.Status == OrderStatus.WaitPay)) {
                                    throw new ServerErrorException(string.Format("商品：{0}，每人最大购买数量为：{1} 件（您已存在该商品的待支付订单）", item.product_name, product_ex.max_quantity));
                                } else {
                                    throw new ServerErrorException(string.Format("商品：{0}，每人最大购买数量为：{1} 件", item.product_name, product_ex.max_quantity));
                                }
                            }
                        }
                        var dics = new Dictionary<string, object> {
                            { "cost_price",product_ex.cost_price}
                        };
                        var order_item = new order_item_dto {
                            product_id = item.product_id,
                            product_name = item.product_name,
                            unit_price = product_ex.price,
                            quantity = item.num,
                            sku_name = item.sku_name,
                            sku_id = item.sku_id,
                            distribute_price = product_ex.distribution_price,
                            thumbnails_url = item.product_main_img,
                            body = dics,
                            order_item_type = product_ex.product_source,
                            active_type = product_ex.activity_type,
                            product_activity_id = product_ex.product_activity_id,
                            red_drill = product_ex.activity_red_drill,
                            isCashPay = model.is_cash_pay
                        };
                        if (!string.IsNullOrEmpty(item.share_no)) {
                            var disMerchant = _iMerchantService.Get(item.share_no);
                            order_item.distribution_id = disMerchant?.id;
                        }
                        if (product_ex.product_source > 0) {
                            ord.order_type = product_ex.product_source;
                        }
                        if (!string.IsNullOrEmpty(item.share_no)) {
                            var merchant = _iMerchantService.Get(item.share_no);
                            order_item.distribution_id = merchant.id;
                            order_item.dis_user = merchant;
                        }
                        ord.order_items.Add(order_item);
                        order_amount += product_ex.price * item.num;
                        drillAmount += product_ex.activity_red_drill * item.num;
                    }
                    disAmount = ord.order_items.Sum(c => c.distribute_price * c.quantity);
                    ord.disAmount = disAmount;
                    ord.order_amount = order_amount + order.freight;
                    ord.pay_amount = ord.order_amount;
                    ord.red_drill = drillAmount;
                    orders.Add(ord);
                }
            }
            mall.orders = orders;
            if (model.buy_user_id > 0) {
                var merchant = _iMerchantService.Get(model.buy_user_id);
                mall.bind_no = merchant.merchant_no;
                mall.orders.ForEach(c => {
                    c.buyer = merchant;
                });
            }
            if (model.shipping_address_id.HasValue && model.shipping_address_id.Value > 0) {
                var shipping = model.shipping[model.shipping_address_id.Value];
                var regionlist = _iRegionService.GetParents(shipping.region_id).ToList();
                mall.shipping = new shipping_model {
                    address = shipping.address,
                    id_card = shipping.id_card,
                    real_name = shipping.real_name,
                    area_id = regionlist.Count == 3 ? regionlist[2].id : 0,
                    city_id = regionlist[1].id,
                    phone = shipping.phone,
                    province_id = regionlist[0].id,
                    region_name = shipping.region.region_name,
                    ship_to = shipping.shipto
                };
            }
            mall.pay_channel = PayChannel.H5Pay;
            string product_name = orders.FirstOrDefault().order_items.FirstOrDefault().product_name;
            if (string.IsNullOrEmpty(product_name))
                product_name = string.Format("商城订单-{0}", DateTime.Now.ToString("yyyyMMddHHmmss"));
            mall.body = product_name;
            mall.req_method = 2;
            mall.pay_code = "H5Pay";
            mall.settle_type = "T1";
            mall.merchant_no = t_RequestMethod.merchant_no;
            mall.method = t_RequestMethod.TOKEN_MALL_PAY_HTML;
            mall.notify = string.Format("{0}/pay/h5_pay_notify", t_RequestMethod.api_url);
            mall.front_notify = string.Format("{0}/MyOrder/OrderList", t_RequestMethod.token_url);
            mall.openid = !string.IsNullOrEmpty(model.wx_open_id) ? model.wx_open_id : model.ip;
            mall.is_wx_pub_account_pay = !string.IsNullOrEmpty(model.wx_open_id) ? true : false;
            mall.nonce = DtoHelper.RandCode(10);
            mall.shipping_type = 1;
            mall.subject = "快捷支付";
            mall.timestamp = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            mall.tran_amount = (Math.Round(model.total_amount * 100, 2)).ToString();
            return mall;
        }

        #region 供应商PC
        /// <summary>
        /// 拓垦商城首页统计
        /// </summary>
        /// <param name="user_id"></param>
        /// <returns></returns>
        public token_merchant_order_count GetOrderCount(long user_id) {
            var orders = context.Orders.Where(c => c.MerchantId == user_id).ToDtoList<order_dto>();
            var bill = context.Bills.Where(c => c.MerchantId == user_id).ToDtoList<bill_dto>();
            var order_count = new token_merchant_order_count();
            order_count.pending_order_num = orders.Where(c => c.status == OrderStatus.WaitDelivery).Count();
            order_count.yesterday_order_num = orders.Where(c => (c.status == OrderStatus.WaitDelivery || c.status == OrderStatus.Confirm || c.status == OrderStatus.Finish || c.status == OrderStatus.Shipped) &&
                                            c.order_time > DateTime.Now.AddDays(-1).AddHours(-(DateTime.Now.Hour)) && c.order_time < DateTime.Now.AddDays(-1).AddHours(+(24 - (DateTime.Now.Hour)))).Count();
            order_count.yesterday_transaction_amount = orders.Where(c => (c.status == OrderStatus.WaitDelivery || c.status == OrderStatus.Confirm || c.status == OrderStatus.Finish || c.status == OrderStatus.Shipped))
                                                        .Select(c => c.pay_amount).Sum();
            order_count.total_transaction_amount = bill.Select(c => c.unconfirmed + c.deposited + c.goods_deposited + c.goods_deposit).Sum();
            return order_count;
        }
        /// <summary>
        /// 修改待支付订单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public int ModifyWaitOrder(spc_modify_wait_pay_order_model dto) {
            if (dto.freight < 0)
                throw new ServerErrorException("运费不能小于0");
            var order = context.Orders.Where(o => o.Id == dto.order_id).FirstOrDefault();
            order.MerchantRemark = dto.merchant_remark;
            if (order.Freight != dto.freight) {//修改运费
                decimal dif_value = dto.freight - order.Freight;
                order.Amount += dif_value;
                order.PayAmount += dif_value;
                order.OrderAmount += dif_value;

                order.Freight = dto.freight;
            }
            //if (dto.order_item_model_list != null && dto.order_item_model_list.Count() > 0) {
            //    foreach (var itemModel in dto.order_item_model_list) {
            //        var orderItem = order.OrderItems.Where(o => o.Id == itemModel.order_item_id).FirstOrDefault();
            //        if(orderItem.UnitPrice != itemModel.unit_price) {
            //            var productActivity = _iProductService.GetCalculateExForActivity(orderItem.ProductId, orderItem.SkuId.HasValue ? orderItem.SkuId.Value : 0, false, orderItem.IsCashPay);
            //            if (itemModel.unit_price < productActivity.cost_price)
            //                throw new ServerErrorException(string.Format("商品：{0} 价格不能小于其成本价", orderItem.ProductName));
            //            //修改商品价格
            //            orderItem.UnitPrice = itemModel.unit_price;
            //            orderItem.IsModifyWaitPayOrder = true;
            //        }
            //    }
            //}
            int result = _iUnitOfWork.Commit("Orders", order.BuyId.HasValue ? "Orders" + order.BuyId : "");
            return result;
        }
        #endregion
        public int OrderShiping(shipping_address_dto dto) {
            var order = context.Orders.FirstOrDefault(c => c.Id == dto.id);
            if (order == null) throw new ServerErrorException("该订单不存在");
            order.Shipping.RealName = dto.real_name;
            order.Shipping.IdCard = dto.id_card;
            order.Shipping.RegionName = dto.region_name;
            int result = _iUnitOfWork.Commit("Orders");
            return result;
        }

        public int SaveOrderNo(string order_no, string new_order_no) {
            var order = context.Orders.FirstOrDefault(c => c.OrderNo == order_no);
            if (order == null)
                throw new ServerErrorException("该订单号不存在");
            var newOrder = context.Orders.FirstOrDefault(c => c.OrderNo == new_order_no);
            if (newOrder != null)
                throw new ServerErrorException("该订单号已存在");
            order.OrderNo = new_order_no;
            order.PushFailMsg = string.Format("该订单已人工下单处理，订单号：{0}", order_no);
            int result = _iUnitOfWork.Commit("Orders");
            return result;
        }

        /// <summary>
        /// 导入发货信息
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public bool ImportDelivery(DataTable dt) {
            if (dt == null || dt.Rows.Count == 0)
                throw new ServerErrorException("所选文件没有数据，请在名为：Sheet1 的工作簿添加数据");
            using (var trans = context.Database.BeginTransaction())//事务处理，文档中一条数据处理异常就回滚事务
            {
                try {
                    List<string> orderNoList = new List<string>();
                    for (var i = 0; i < dt.Rows.Count; i++) {
                        var order_no = dt.Rows[i][3].ToString();
                        var tno = dt.Rows[i][2].ToString();
                        var name = dt.Rows[i][0].ToString();
                        var tcode = dt.Rows[i][1].ToString();
                        if (orderNoList.Exists(o => o == order_no))
                            throw new ServerErrorException(string.Format("订单号：{0} 在文档中重复出现", order_no));
                        orderNoList.Add(order_no);
                        if (string.IsNullOrEmpty(name))
                            throw new ServerErrorException(string.Format("第{0}行快递公司为空", i + 2));
                        if (string.IsNullOrEmpty(tcode))
                            throw new ServerErrorException(string.Format("第{0}行快递编码为空", i + 2));
                        if (string.IsNullOrEmpty(tno))
                            throw new ServerErrorException(string.Format("第{0}行快递单号为空", i + 2));
                        if (string.IsNullOrEmpty(order_no))
                            throw new ServerErrorException(string.Format("第{0}行的订单号为空", i + 2));

                        var order = context.Orders.FirstOrDefault(o => o.OrderNo == order_no);
                        if (order == null)
                            throw new ServerErrorException(string.Format("订单号：{0} 不存在", order_no));
                        if (order.Status != OrderStatus.WaitDelivery)
                            throw new ServerErrorException(string.Format("订单号：{0} 非待发货状态不能发货", order_no));

                    }
                    //直接调用发货方法，会发送Jpush信息，所以要先循环判断Excel表格中数据是否正确（如果表格中数据有误，已修改的状态会回滚），循环判断通过后，再调用发货方法
                    for (var i = 0; i < dt.Rows.Count; i++) {
                        var order_no = dt.Rows[i][3].ToString();
                        var tno = dt.Rows[i][2].ToString();
                        var name = dt.Rows[i][0].ToString();
                        var tcode = dt.Rows[i][1].ToString();

                        OrderDelivery(new order_dto_ex { express_company_name = name, express_no = tcode, order_no = order_no, ship_order_number = tno });//会发消息
                    }
                    trans.Commit();
                    return true;
                } catch (ServerErrorException ex) {
                    trans.Rollback();
                    throw ex;
                } catch (Exception ex) {
                    trans.Rollback();
                    throw ex;
                }


            }
        }
        public mall_model GetFaceMall(long merchantId, string ip) {
            var member = _iMerchantService.Get(merchantId);
            var mall = new mall_model { order_no = DtoHelper.GenerateOrderNumber(), source_type = 3 };
            decimal price = t_RequestMethod.TOKEN_FACE_Pay_Money;
            var orderitems = new List<order_item_dto>();
            var dics = new Dictionary<string, object> {
                            { "cost_price",price}
                        };
            var order_item = new order_item_dto() {
                product_id = 0,
                bazaar_product_id = 0,
                product_name = "人脸认证",
                unit_price = price,
                market_price = price,
                quantity = 1,
                sku_name = "",
                sku_id = 0,
                distribute_price = 0,
                thumbnails_url = string.Empty,
                body = dics,
                order_item_type = 7,
                active_type = 0,
                product_activity_id = 0,
                red_drill = 0,
                isCashPay = true,
            };
            var merchant_no = t_RequestMethod.TOKEN_MARKETING_DEFAULT_MEARCHANTNO;
            var sell_merchant = _iMerchantService.Get(merchant_no);
            var orders = new List<order_dto>();
            var order = new order_dto {
                order_no = DtoHelper.GenerateOrderNumber(),
                status = OrderStatus.WaitPay,
                order_time = DateTime.Now,
                buy_id = merchantId,
                freight = 0,
                merchant_id = sell_merchant.id,
                remark = "",
                order_type = 7,


            };
            orderitems.Add(order_item);
            order.order_items = orderitems;
            order.order_amount = price * order_item.quantity;
            order.pay_amount = order.order_amount;
            order.red_drill = 0;
            orders.Add(order);
            mall.orders = orders;
            mall.bind_no = member.merchant_no;
            mall.orders.ForEach(c => {
                c.buyer = member;
            });

            mall.shipping = new shipping_model {
                address = string.Empty,
                id_card = string.Empty,
                real_name = string.Empty,
                area_id = 0,
                city_id = 0,
                phone = string.Empty,
                province_id = 0,
                region_name = string.Empty,
                ship_to = string.Empty
            };
            mall.pay_channel = PayChannel.H5Pay;
            string product_name = "人脸认证";
            if (string.IsNullOrEmpty(product_name))
                product_name = string.Format("实人认证订单-{0}", DateTime.Now.ToString("yyyyMMddHHmmss"));
            mall.body = product_name;
            mall.req_method = 2;
            mall.pay_code = "H5Pay";
            mall.settle_type = "T1";
            mall.merchant_no = t_RequestMethod.merchant_no;
            mall.method = t_RequestMethod.TOKEN_MALL_PAY_HTML;
            mall.notify = string.Format("{0}/pay/h5_pay_notify", t_RequestMethod.api_url);
            mall.front_notify = string.Format("{0}/Order/PayFinish", t_RequestMethod.token_url);
            mall.openid = ip;
            mall.is_wx_pub_account_pay = false;
            mall.nonce = DtoHelper.RandCode(10);
            mall.shipping_type = 1;
            mall.subject = "快捷支付";
            mall.timestamp = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            mall.tran_amount = (Math.Round(price * 100, 2)).ToString();
            return mall;
        }
    }
}
